package com.aquarium.ui;

import java.util.Observable;
import java.util.Observer;

import com.aquarium.R;
import com.aquarium.bt.BTManager;
import com.aquarium.bt.DataInterpreter;
import com.aquarium.bt.DataStruct;
import com.aquarium.security.SecurityManager;
import com.aquarium.config.BTCommand;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class SecurityActivity extends Activity implements Observer {
	private static final String TAG = "SecurityActivity";

	private static final int TIMEOUT_VALUE = 5000;

	private static final int MESSAGE_REQUEST_COMMUNICATE = 0x12;
	private static final int MESSAGE_RECEIVE_DATA_TIMEOUT = 0x15;
	private static final int MESSAGE_COMMUNICATE_SUCCESS = 0x16;
	private static final int MESSAGE_COMMUNICATE_FAIL = 0x17;
	private static final int MESSAGE_COMMUNICATE_IN_PROGRESS = 0x19;

	private Context mContext;

	private SecurityManager mSecurityManager;
	private BTManager mBtManager;

	private EditText mPasswordEditText;
	private CheckBox mStorePasswordBox;

	private ImageView mOkButton;
	private ImageView mCancelButton;

	private ProgressDialog mProgressDialog;
	/**
	 * the password user input.
	 */
	private String mPassword;

	/**
	 * true means user check to remember password.
	 */
	private boolean bRememberPassword = false;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.security);
		mContext = SecurityActivity.this;

		mSecurityManager = SecurityManager.getInstance(mContext);
		mBtManager = BTManager.getInstance();
		mBtManager.addObserver(this);

		mOkButton = (ImageView) findViewById(R.id.ok);
		mCancelButton = (ImageView) findViewById(R.id.cancel);
		mPasswordEditText = (EditText) findViewById(R.id.password);
		mStorePasswordBox = (CheckBox) findViewById(R.id.remenber_password);
		
		bRememberPassword = mSecurityManager.isStoredPassword();
		mStorePasswordBox.setChecked(bRememberPassword);
		if(bRememberPassword){
			mPassword = mSecurityManager.getPassword();
			mPasswordEditText.setText(mPassword);
		}

		mOkButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				mPassword = mPasswordEditText.getText().toString();
				bRememberPassword = mStorePasswordBox.isSelected();
				sendSetPasswordData(mPassword);
			}
		});

		mCancelButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {

				finish();
			}
		});
	}

	private Handler mHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case MESSAGE_REQUEST_COMMUNICATE:

				break;
			case MESSAGE_COMMUNICATE_IN_PROGRESS:
				showProgressDialog();
				break;

			case MESSAGE_COMMUNICATE_SUCCESS:
				mProgressDialog.dismiss();
				showToast(getString(R.string.set_success));
				// save password
				if (bRememberPassword) {
					mSecurityManager.setNeedStorePassword(true);
					mSecurityManager.storePassword(mPassword);
				}else {
					mSecurityManager.setNeedStorePassword(false);
				}
				finish();
				break;
			case MESSAGE_COMMUNICATE_FAIL:
				mProgressDialog.dismiss();
				showFailDialog(getString(R.string.set_fail));
				break;
			case MESSAGE_RECEIVE_DATA_TIMEOUT:
				mProgressDialog.dismiss();
				showToast(getString(R.string.set_timeout));
				break;
			default:
				break;
			}

		};
	};

	@Override
	protected void onDestroy() {
		mBtManager.deleteObserver(this);
		super.onDestroy();
	}

	private void showFailDialog(String message) {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		LayoutInflater inflater = this.getLayoutInflater();
		final View authFailView = inflater.inflate(
				R.layout.dialog_authentication_fail, null);
		((TextView) authFailView.findViewById(R.id.auth_fail_message))
				.setText(message);

		builder.setView(authFailView)
				.setTitle(getText(R.string.error))
				.setPositiveButton(R.string.ok,
						new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int id) {
								dialog.dismiss();
							}
						}).create().show();
	}

	private void sendSetPasswordData(String password) {
		final byte[] passwordBytes = BTCommand.getSetPasswdCommand(password);
		if (passwordBytes == null) {
			showFailDialog(getString(R.string.password_length_error));
			return;
		}

		mBtManager.sendData(DataInterpreter.unpack(passwordBytes));
		mHandler.sendEmptyMessageDelayed(MESSAGE_RECEIVE_DATA_TIMEOUT,
				TIMEOUT_VALUE);
		mHandler.sendEmptyMessage(MESSAGE_COMMUNICATE_IN_PROGRESS);

		// test code TODO
		SystemClock.sleep(1000);
//		 if ("0000".equals(password)) {
//		 mBtManager.sendPasswdVarifyOk();
//		 } else {
//		 mBtManager.sendPasswdVarifyFail();
//		 }
	}

	private void showProgressDialog() {
		mProgressDialog = new ProgressDialog(mContext);
		mProgressDialog.setMessage(getText(R.string.please_wait));
		mProgressDialog.setCancelable(false);
		mProgressDialog.show();
	}

	private void showToast(String content) {
		Toast.makeText(mContext, content, Toast.LENGTH_SHORT).show();
	}

	@Override
	public void update(Observable observable, Object data) {
		if (observable instanceof BTManager) {
			// timeout already.
			if(!mHandler.hasMessages(MESSAGE_RECEIVE_DATA_TIMEOUT)){
				return;
			}
			final DataStruct receivedData = (DataStruct) data;
			byte[] resposeData = DataInterpreter.pack(receivedData);
			Log.d(TAG, "get responce, length:" + resposeData.length);

			if (receivedData.prefix == 0x5a && receivedData.id == 0x01
					&& receivedData.code == 0x60 && receivedData.length == 0x01) {
				Log.d(TAG, "get responce data of setting password");
				mHandler.removeMessages(MESSAGE_RECEIVE_DATA_TIMEOUT);
				if (receivedData.data[0] == 0x00) {
					// authentication success
					mHandler.sendEmptyMessage(MESSAGE_COMMUNICATE_SUCCESS);
				} else if (receivedData.data[0] == 0x01) {
					// authentication fail, request again
					mHandler.sendEmptyMessage(MESSAGE_COMMUNICATE_FAIL);
				}
			}
		}
	}
}
